package com.ruoyi.web.controller.thirdAPI;

import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.constant.TaxConstants;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpClientUtil;
import com.ruoyi.system.domain.WaterMeter;
import com.ruoyi.system.domain.WaterYcmeterDatahistory;
import com.ruoyi.system.domain.tax.BaseResponse;
import com.ruoyi.system.domain.tax.FluxPressureData;
import com.ruoyi.system.domain.xtkj.*;
import com.ruoyi.system.service.IWaterInterfaceService;
import com.ruoyi.system.service.IWaterMeterService;
import com.ruoyi.system.service.IWaterYcmeterDatahistoryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Administrator
 * @description 新天科技水表数据接口 五分钟采集一次，6个小时上报一次 历史数据 最多存储一周
 * @data 2025/10/15 8:56
 */

@Controller
@RequestMapping("/xtkjApi")
public class XtkjDataController {

    private static final Logger log = LoggerFactory.getLogger(XtkjDataController.class);

    @Autowired
    private IWaterYcmeterDatahistoryService historyService;
    @Autowired
    private IWaterMeterService waterMeterService;
    @Autowired
    private IWaterInterfaceService waterInterfaceService;
    @Autowired
    private HttpClientUtil httpClientUtil;
    @Autowired
    private ObjectMapper objectMapper;
    private String accessToken;
    private long tokenExpiryTime;

    // 获取token 过期时间2小时  2025-10-15 15:57:30
    private static final String TOKEN = "25764c887b0164ed7ae95c019274b14df4dc8f0f975b9363da5f9bdeebde96b4";

    @PostMapping("/getToken")
    @ResponseBody
    public boolean getToken(){
        String url = TaxConstants.BASE_URL + "/ApiKeyApi/GetToken";
        try {
            String requestBody = "{\"ak_key\":\"" + TaxConstants.APP_KEY + "\",\"ak_secret\":\"" + TaxConstants.APP_SECRET + "\"}";
            String responseBody = httpClientUtil.post(url, requestBody, null);
            XTApiResponse<TokenData> apiResponse = objectMapper.readValue(
                    responseBody, new TypeReference<XTApiResponse<TokenData>>() {});
            if (apiResponse.isSuccess() && apiResponse.getData() != null) {
                accessToken = apiResponse.getData().getAccessToken();
                tokenExpiryTime = System.currentTimeMillis() + apiResponse.getData().getExpiryMinutes() * 60 * 1000;
                log.info("Token获取成功，Token: {}", accessToken);
                log.info("Token获取成功，过期时间: {}", apiResponse.getData().getExpiryTime());
                return true;
            }
        } catch (Exception e) {
            log.error("获取Token时发生异常", e);
        }
        return false;
    }

    // 定义四个时间点
    private static final List<LocalTime> TIME_POINTS = Arrays.asList(
            LocalTime.of(0, 0),   // 0点
            LocalTime.of(6, 0),   // 6点
            LocalTime.of(12, 0),  // 12点
            LocalTime.of(18, 0)   // 18点
    );
    @PostMapping("/test")
    @ResponseBody
    public void test(){
        WaterMeter waterMeter = new WaterMeter();
        waterMeter.setMeterType("0"); // 0:远传表
        List<WaterMeter> waterMeters =waterMeterService.selectWaterMeterList(waterMeter);
        List<WaterYcmeterDatahistory> waterDataList = waterInterfaceService.selectCYWaterMeterData();
        if (StringUtils.isNotEmpty(waterDataList)){
            Map<String,WaterYcmeterDatahistory> waterDataMap = waterDataList.stream().collect(Collectors.toMap(
                    WaterYcmeterDatahistory::getMeterNo,
                    item -> item,
                    // 使用字符串比较，取最大的字符串（即最近的日期）
                    (existing, replacement) -> existing.getReadDate().compareTo(replacement.getReadDate()) > 0 ? existing : replacement
            ));
            LocalTime timePoint = DateUtils.findNearestTimePointSimplified(TIME_POINTS, LocalTime.now());
            for (WaterMeter meter : waterMeters) {
                if("CY".equals(meter.getMaker())){  // 创源水表
                    WaterYcmeterDatahistory realData = waterDataMap.get(meter.getMeterNo());
                    if(realData==null){
                        continue;
                    }
                    realData.setReadDate(DateUtils.getDate()+" " + timePoint);
                    waterInterfaceService.syncCYWaterMeterRealData(meter,realData);
                }
            }
        }
    }

    /**
     * 流量计实时数据
     * @param meterNo 水表编号
     * @return
     */
    @PostMapping("/getFlowMonitorRealData")
    @ResponseBody
    public void getWaterFlowMonitorData(String meterNo){
        XTApiResponse<PageDataResponse<FlowMeterRealData>> response = getFlowMeterRealData(null, meterNo, null, 1, 10);
        PageDataResponse<FlowMeterRealData> pageData = response.getData();
        for (FlowMeterRealData device : pageData.getDataInfo()) {
            System.out.println("\n设备信息:");
            System.out.println("  设备ID: " + device.getDataPointId());
            System.out.println("  设备名称: " + device.getDataPointName());
            System.out.println("  点位编码: " + device.getPointCode());
            System.out.println("  采集时间: " + device.getReadDate());
            System.out.println("  安装地址: " + device.getInstallationAddr());
            // 使用数据处理器提取具体数值
            if (device.getRealData() != null) {
                System.out.println("  实时数据:");
                // 提取正瞬时流量
                Optional<Double> positiveFlow = DataProcessor.getRealDataNumericValue(
                        device.getRealData(), "iPositiveFlowRate");
                positiveFlow.ifPresent(value ->
                        System.out.println("    正瞬时流量: " + value + " m³/h"));

                // 提取正累计流量
                Optional<Double> positiveAccumulative = DataProcessor.getRealDataNumericValue(
                        device.getRealData(), "iPositiveAccumulativeFlow");
                positiveAccumulative.ifPresent(value ->
                        System.out.println("    正累计流量: " + value + " m³"));

                // 提取压力值
                Optional<Double> pressure = DataProcessor.getRealDataNumericValue(
                        device.getRealData(), "np");
                pressure.ifPresent(value ->
                        System.out.println("    压力: " + value + " MPa"));
            }
        }
    }

    @PostMapping("/getFlowMonitorHistoryData2")
    public BaseResponse<FluxPressureData> getFluxPressureData(String startTime) {
        WaterMeter waterMeter = new WaterMeter();
        waterMeter.setMeterType("0"); // 0:远传表
        List<WaterMeter> waterMeters =waterMeterService.selectWaterMeterList(waterMeter);
//        Calendar calendar = Calendar.getInstance();
//        calendar.add(Calendar.MINUTE, -5);
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
//        String startTime = "2025-10-27 06:00:00";
        LocalDateTime date = LocalDateTime.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
        String endTime = date.plusHours(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
//        String endTime = "2025-10-27 07:00:00";
        for(WaterMeter meter : waterMeters){
//            if(meter.getMeterNo().equals("25090130910")){
            if("XTKJ".equals(meter.getCreateBy())){  // 新天科技水表
                waterInterfaceService.syncXTKJWaterMeterData(meter,startTime,endTime);
            }
        }
        return null;
    }

    /**
     * 流量计历史数据
     * @param meterNo 水表编号
     * @return
     */
    @PostMapping("/getFlowMonitorHistoryData")
    @ResponseBody
    public void getWaterFlowMonitorHistoryData2(String meterNo,String time){
        LocalDate date = LocalDate.parse(time);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        // 时间段1: 23:58-00:01 (23:58用前一天日期)
        LocalDateTime start1 = LocalDateTime.of(date.minusDays(1), LocalTime.of(23, 58));
        LocalDateTime end1 = LocalDateTime.of(date, LocalTime.of(0, 1));
        String startTime1 = start1.format(formatter);
        String endTime1 = end1.format(formatter);
        getWaterFlowMonitorHistoryData1(meterNo, startTime1, endTime1);
        // 时间段2: 05:58-06:01 (当天日期)
        LocalDateTime start2 = LocalDateTime.of(date, LocalTime.of(5, 58));
        LocalDateTime end2 = LocalDateTime.of(date, LocalTime.of(6, 1));
        String startTime2 = start2.format(formatter);
        String endTime2 = end2.format(formatter);
        getWaterFlowMonitorHistoryData1(meterNo, startTime2, endTime2);
        // 时间段3: 11:58-12:01 (当天日期)
        LocalDateTime start3 = LocalDateTime.of(date, LocalTime.of(11, 58));
        LocalDateTime end3 = LocalDateTime.of(date, LocalTime.of(13, 1));
        String startTime3 = start3.format(formatter);
        String endTime3 = end3.format(formatter);
        getWaterFlowMonitorHistoryData1(meterNo, startTime3, endTime3);
        // 时间段4: 17:58-18:01 (当天日期)
        LocalDateTime start4 = LocalDateTime.of(date, LocalTime.of(17, 58));
        LocalDateTime end4 = LocalDateTime.of(date, LocalTime.of(18, 1));
        String startTime4 = start4.format(formatter);
        String endTime4 = end4.format(formatter);
        getWaterFlowMonitorHistoryData1(meterNo, startTime4, endTime4);
    }

    /**
     * 流量计历史数据
     * @param meterNo 水表编号
     * @return
     */
    @PostMapping("/getFlowMonitorHistoryData1")
    @ResponseBody
    public void getWaterFlowMonitorHistoryData1(String meterNo,String startTime,String endTime){
        startTime = "2025-10-25 20:00:00";
//        String startTime = DateUtils.getPreviousDay(endTime) +" 00:00";
        endTime = "2025-10-26 01:00:00";
//        String endTime = DateUtils.getTime();
        XTApiResponse<PageDataResponse<FlowMeterHistoryData>> response = getFlowMeterHistoryData(meterNo, startTime, endTime, 1, 289);
        PageDataResponse<FlowMeterHistoryData> pageData = response.getData();
        System.err.println("历史数据:"+ JSONUtil.toJsonStr(pageData.getDataInfo()));

    }

    /**
     * 检查Token是否有效
     */
    private boolean isTokenValid() {
        return accessToken != null && System.currentTimeMillis() < tokenExpiryTime - 60000; // 提前1分钟刷新
    }

    /**
     * 执行api请求
     */
//    private <T> XTApiResponse<T> executeRequest(String url, Object requestBody, TypeReference<XTApiResponse<T>> typeReference) {
    private <T> XTApiResponse<PageDataResponse<T>> executePageRequest(String url, Object requestBody, Class<T> elementType) {
    try {
            String jsonBody = objectMapper.writeValueAsString(requestBody);
            Map<String, String> headers = new HashMap<>();
            if(!isTokenValid()){ // 如果Token已过期，则重新获取
                getToken();
            }
            headers.put("access-token", accessToken);
            System.err.println("请求地址："+url);
            System.err.println("请求参数："+jsonBody);
            String responseBody = httpClientUtil.post(url, jsonBody, headers);
            System.err.println(responseBody);
            // 构造分页响应类型
            JavaType pageDataType = objectMapper.getTypeFactory().constructParametricType(
                    PageDataResponse.class, elementType);
            JavaType responseType = objectMapper.getTypeFactory().constructParametricType(
                    XTApiResponse.class, pageDataType);
            return objectMapper.readValue(responseBody, responseType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    // 流量计实时数据
    public XTApiResponse<PageDataResponse<FlowMeterRealData>> getFlowMeterRealData(
            String pointCode, String pointName, Integer meteringType, Integer page, Integer rows) {

        Map<String, Object> requestBody = new HashMap<>();
        if (pointCode != null) {
            requestBody.put("PointCode", pointCode);
        }
        if (pointName != null) {
            requestBody.put("PointName", pointName);
        }
        if (meteringType != null) {
            requestBody.put("MeteringType", meteringType);
        }
        if (page != null) {
            requestBody.put("Page", page);
        }
        if (rows != null) {
            requestBody.put("Rows", rows);
        }

        String url = TaxConstants.BASE_URL + "/Bussiness_FlowMonitorApi/GetRealData";
        return executePageRequest(url, requestBody, FlowMeterRealData.class);
    }

    // 流量计历史数据
    public XTApiResponse<PageDataResponse<FlowMeterHistoryData>> getFlowMeterHistoryData(
            String dataPointId, String startTime, String endTime, Integer page, Integer rows) {

        Map<String, Object> requestBody = new HashMap<>();
        if (dataPointId != null) {
            requestBody.put("DataPointID", dataPointId);
        }
        if (startTime != null) {
            requestBody.put("StartTime", startTime);
        }
        if (endTime != null) {
            requestBody.put("EndTime", endTime);
        }
        if (page != null) {
            requestBody.put("Page", page);
        }
        if (rows != null) {
            requestBody.put("Rows", rows);
        }

        String url = TaxConstants.BASE_URL + "/Bussiness_FlowMonitorApi/GetHistoryData";
        return executePageRequest(url, requestBody, FlowMeterHistoryData.class);
    }

}
